package com.personal.system.controller.seckill;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.personal.common.result.Result;
import com.personal.common.utils.JwtHelper;
import com.personal.system.entity.seckill.SeckillGoods;
import com.personal.system.entity.seckill.SeckillOrder;
import com.personal.system.service.SeckillService;
import com.personal.system.service.sys.SysUserService;
import com.personal.system.listener.mq.MqSender;
import com.personal.system.listener.mq.SeckillMessage;
import com.personal.system.constant.redis.GoodsKey;
import com.personal.system.constant.redis.RedisService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;

@Api(tags = "秒杀控制器")
@RequestMapping("/seckill")
@RestController
public class SeckillController implements InitializingBean {

    @Resource
    private SeckillService seckillService;
    @Resource
    private RedisService redisService;
    @Resource
    private MqSender mqSender;
    @Resource
    private SysUserService userService;

    /**
     * 如果是集群情况下，需要达到一定量此缓存才能起到重大作用
     */
    private final HashMap<Long, Boolean> localOverMap = new HashMap<>();

    @Override
    public void afterPropertiesSet() {
        List<SeckillGoods> goodsList = (List<SeckillGoods>)seckillService.getSeckillGoodsList(null);
        if (goodsList == null) return;
        for (SeckillGoods goods : goodsList) {
            redisService.set(GoodsKey.getSeckillGoodsStock, String.valueOf(goods.getId()), goods.getStockCount(), 60 * 30 * 24);
            localOverMap.put(goods.getId(), false);
        }
    }

    @GetMapping("/getPageList/{page}/{limit}")
    public Result getPageList(@PathVariable Long page, @PathVariable Long limit) {

        Page<SeckillGoods> pageParam = new Page<>(page, limit);
        IPage<SeckillGoods> pageModel = seckillService.selectPage(pageParam);
        return Result.ok(pageModel);
    }

    @GetMapping("/getById/{id}")
    public Result getById(@PathVariable Long id) {

        return Result.ok( seckillService.getById(id));
    }

    @GetMapping("/getPath/{goodsId}")
    public Result getPath(@PathVariable Long goodsId) {

        return Result.ok( seckillService.getPath(goodsId));
    }

    @PostMapping("/{path}/seckill")
    public Result list(@RequestParam("goodsId") long goodsId, @PathVariable("path") String path,
                                                                    HttpServletRequest request) {

        boolean check = seckillService.checkPath(goodsId,path);
        if (!check) return Result.fail("请求非法");

        // 内存标记，减少redis访问
        Boolean over = localOverMap.get(goodsId);
        if (over) return Result.fail("商品已经秒杀完毕");

        // 预减库存
        Long stock = redisService.decr(GoodsKey.getSeckillGoodsStock, String.valueOf(goodsId));
        if (stock < 0){
            localOverMap.put(goodsId, true);
            return Result.fail("商品已经秒杀完毕");
        }

        // 判断是否秒杀到了
        SeckillOrder order = seckillService.getOrderByUserNameGoodsId(null,goodsId);
        if (order != null) return Result.fail("不能重复秒杀");

        String userId = JwtHelper.getUser(request.getHeader("token")).get("userId").toString();

        // 进来队列
        SeckillMessage message = new SeckillMessage();
        message.setUser(userService.getById(userId));
        message.setGoodsId(goodsId);
        mqSender.sendSeckillMsg(message);

        return Result.ok("ok");
    }

    @GetMapping("/result")
    public Result miaoResult(@RequestParam("goodsId") long goodsId) {

        long result = seckillService.getMiaoResult(goodsId);
        return Result.ok(result);
    }

}
